<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/%E6%AD%A6%E6%B1%8932x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/%E6%AD%A6%E6%B1%8916x16.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib1/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="/lib1/pace/pace-theme-center-simple.min.css">
  <script src="/lib1/pace/pace.min.js"></script>

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"example.com","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="初识设计模式设计模式原则单一职责原则单一职责原则(Single Responsibility Principle,SRP)：一个类只负责一个功能领域中的相应职责，或者可以定义为：就一个类而言，应该只有一个引起它变化的原因。 单一职责原则是实现高内聚、低耦合的指导方针，它是最简单但又最难运用的原则，需要设计人员发现类的不同职责并将其分离，而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践">
<meta property="og:type" content="article">
<meta property="og:title" content="初识设计模式">
<meta property="og:url" content="http://example.com/2021/07/22/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/index.html">
<meta property="og:site_name" content="Technological Blog">
<meta property="og:description" content="初识设计模式设计模式原则单一职责原则单一职责原则(Single Responsibility Principle,SRP)：一个类只负责一个功能领域中的相应职责，或者可以定义为：就一个类而言，应该只有一个引起它变化的原因。 单一职责原则是实现高内聚、低耦合的指导方针，它是最简单但又最难运用的原则，需要设计人员发现类的不同职责并将其分离，而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.PNG">
<meta property="og:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F.PNG">
<meta property="article:published_time" content="2021-07-22T11:42:38.000Z">
<meta property="article:modified_time" content="2021-11-03T08:27:29.078Z">
<meta property="article:author" content="Li Yudong">
<meta property="article:tag" content="设计模式">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://example.com/image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.PNG">

<link rel="canonical" href="http://example.com/2021/07/22/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>初识设计模式 | Technological Blog</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Technological Blog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">IT小白的成长之旅</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="tags fa-fw"></i>标签<span class="badge">18</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="th fa-fw"></i>分类<span class="badge">14</span></a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="archive fa-fw"></i>归档<span class="badge">95</span></a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <a href="https://github.com/tiarmor1" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/07/22/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/author.jpg">
      <meta itemprop="name" content="Li Yudong">
      <meta itemprop="description" content="">
    </span>
    
    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Technological Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          初识设计模式
        </h1>
    
        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
    
              <time title="创建时间：2021-07-22 19:42:38" itemprop="dateCreated datePublished" datetime="2021-07-22T19:42:38+08:00">2021-07-22</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-11-03 16:27:29" itemprop="dateModified" datetime="2021-11-03T16:27:29+08:00">2021-11-03</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" itemprop="url" rel="index"><span itemprop="name">设计模式</span></a>
                </span>
            </span>
    
          
    
        </div>
      </header>
    
    
    
    
    <div class="post-body" itemprop="articleBody">
    
      
        <h1 id="初识设计模式"><a href="#初识设计模式" class="headerlink" title="初识设计模式"></a>初识设计模式</h1><h2 id="设计模式原则"><a href="#设计模式原则" class="headerlink" title="设计模式原则"></a>设计模式原则</h2><h3 id="单一职责原则"><a href="#单一职责原则" class="headerlink" title="单一职责原则"></a>单一职责原则</h3><p><strong>单一职责原则(Single Responsibility Principle,SRP)：一个类只负责一个功能领域中的相应职责，或者可以定义为：就一个类而言，应该只有一个引起它变化的原因。</strong> 单一职责原则是实现高内聚、低耦合的指导方针，它是最简单但又最难运用的原则，需要设计人员发现类的不同职责并将其分离，而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。 </p>
<h3 id="开放封闭原则"><a href="#开放封闭原则" class="headerlink" title="开放封闭原则"></a>开放封闭原则</h3><p> <strong>开闭原则(Open-Closed Principle,OCP)：一个软件实体应当对扩展开放，对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。</strong> 开闭原则是面向对象的可复用设计的第一块基石，它是最重要的面向对象设计原则。在开闭原则的定义中，软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。 </p>
<p>为了满足开闭原则，需要对系统进行抽象化设计，抽象化是开闭原则的关键。在Java、C#等编程语言中，可以为系统定义一个相对稳定的抽象层，而将不同的实现行为移至具体的实现层中完成。在很多面向对象编程语言中都提供了接口、抽象类等机制，可以通过它们定义系统的抽象层，再通过具体类来进行扩展。如果需要修改系统的行为，无须对抽象层进行任何改动，只需要增加新的具体类来实现新的业务功能即可，实现在不修改已有代码的基础上扩展系统的功能，达到开闭原则的要求。 </p>
<p>因为xml和properties等格式的配置文件是纯文本文件，可以直接通过编辑器进行编辑，且无须编译，因此在软件开发中，一般不把对配置文件的修改认为是对系统源代码的修改。如果一个系统在扩展时只涉及到修改配置文件，而原有的Java代码或C#代码没有做任何修改，该系统即可认为是一个符合开闭原则的系统。 </p>
<h3 id="里氏代换原则"><a href="#里氏代换原则" class="headerlink" title="里氏代换原则"></a>里氏代换原则</h3><p><strong>里氏代换原则(Liskov Substitution Principle,LSP)：所有引用基类（父类）的地方必须能透明地使用其子类的对象。 正式由于子类型的可替换性，才使得使用父类类型的模块在无需修改的情况下就可以进行扩展。</strong></p>
<p>里氏代换原则是实现开闭原则的重要方式之一，由于使用基类对象的地方都可以使用子类对象，因此在程序中尽量使用基类类型来对对象进行定义，而在运行时再确定其子类类型，用子类对象来替换父类对象。在使用里氏代换原则时需要注意如下几个问题： </p>
<p>(1)：子类的所有方法必须在父类中声明，或子类必须实现父类中声明的所有方法。根据里氏代换原则，为了保证系统的扩展性，在程序中通常使用父类来进行定义，如果一个方法只存在子类中，在父类中不提供相应的声明，则无法在以父类定义的对象中使用该方法。 </p>
<p>(2)：在运用里氏代换原则时，尽量把父类设计为抽象类或者接口，让子类继承父类或实现父接口，并实现在父类中声明的方法，运行时，子类实例替换父类实例，可以很方便地扩展系统的功能，同时无须修改原有子类的代码，增加新的功能可以通过增加一个新的子类来实现。 </p>
<h3 id="依赖倒转原则"><a href="#依赖倒转原则" class="headerlink" title="依赖倒转原则"></a>依赖倒转原则</h3><p><strong>依赖倒转原则(Dependency Inversion Principle,DIP)：抽象不应该依赖于细节，细节应当依赖于抽象。换言之，要针对接口编程，而不是针对实现编程。（高层模块不应该依赖低层模块，两个都应该依赖抽象）。</strong></p>
<p>依赖倒转原则是面向对象设计的主要实现机制之一，它是系统抽象化的具体实现。 依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中，尽量引用层次高的抽象层类，即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明，以及数据类型的转换等，而不要用具体类来做这些事情。</p>
<p>为了确保该原则的应用，一个具体类应当只实现接口或抽象类中声明过的方法，而不要给出多余的方法，否则将无法调用到在子类中增加的新方法。 在实现依赖倒转原则时，需要针对抽象层编程，而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中，依赖注入是指当一个对象要与其他对象发生依赖关系时，通过抽象来注入所依赖的对象。</p>
<p>常用的注入方式有三种，分别是：构造注入，设值注入（Setter注入）和接口注入。构造注入是指通过构造函数来传入具体类的对象，设值注入是指通过Setter方法来传入具体类的对象，而接口注入是指通过在接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型，在运行时再传入具体类型的对象，由子类对象来覆盖父类对象。 依赖倒转其实可以说是面向对象设计的标志，如果编写的时候考虑的都是如何针对抽象编程而不是针对细节编程，即程序中所有的依赖关系都是终止于抽象类或者接口，则为面向对象的设计。 </p>
<h3 id="接口隔离原则"><a href="#接口隔离原则" class="headerlink" title="接口隔离原则"></a>接口隔离原则</h3><p><strong>接口隔离原则(Interface Segregation Principle,ISP)：使用多个专门的接口，而不使用单一的总接口，即客户端不应该依赖那些它不需要的接口。</strong> </p>
<p>根据接口隔离原则，当一个接口太大时，我们需要将它分割成一些更细小的接口，使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独立的角色，不干不该干的事，该干的事都要干。这里的“接口”往往有两种不同的含义：一种是指一个类型所具有的方法特征的集合，仅仅是一种逻辑上的抽象；另外一种是指某种语言具体的“接口”定义，有严格的定义和结构，比如Java语言中的interface。对于这两种不同的含义，ISP的表达方式以及含义都有所不同： </p>
<p>(1)： 当把“接口”理解成一个类型所提供的所有方法特征的集合的时候，这就是一种逻辑上的概念，接口的划分将直接带来类型的划分。可以把接口理解成角色，一个接口只能代表一个角色，每个角色都有它特定的一个接口，此时，这个原则可以叫做“角色隔离原则”。</p>
<p>(2)： 如果把“接口”理解成狭义的特定语言的接口，那么ISP表达的意思是指接口仅仅提供客户端需要的行为，客户端不需要的行为则隐藏起来，应当为客户端提供尽可能小的单独的接口，而不要提供大的总接口，比如实现中还有还有自己的一些封装的功能方法，而对于每一个接口实现类，可能这些功能代码可能不同。在面向对象编程语言中，实现一个接口就需要实现该接口中定义的所有方法，因此大的总接口使用起来不一定很方便，为了使接口的职责单一，需要将大接口中的方法根据其职责不同分别放在不同的小接口中，以确保每个接口使用起来都较为方便，并都承担某一单一角色。</p>
<p>接口应该尽量细化，同时接口中的方法应该尽量少，每个接口中只包含一个客户端（如子模块或业务逻辑类）所需的方法即可，这种机制也称为“定制服务”，即为不同的客户端提供宽窄不同的接口。 在使用接口隔离原则时，需要注意控制接口的粒度，接口不能太小，如果太小会导致系统中接口泛滥，不利于维护；接口也不能太大，太大的接口将违背接口隔离原则，灵活性较差，使用起来很不方便。 </p>
<h3 id="迪米特法则"><a href="#迪米特法则" class="headerlink" title="迪米特法则"></a>迪米特法则</h3><p><strong>迪米特法则(Law of Demeter,LoD)：又叫作最少知道原则（Least Knowledge Principle, LKP），一个软件实体应当尽可能少地与其他实体发生相互作用。</strong>就是说一个对象应当对其他对象有尽可能少的了解，不和陌生人说话。 如果两个类不必彼此直接通信，那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话，可以通过第三者转发这个调用。 </p>
<p>迪米特法则可降低系统的耦合度，使类与类之间保持松散的耦合关系。迪米特法则可以简单说成：talk only to your immediate friends。 对于LOD来说，又被解释为下面几种方式：一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识，而且局限于那些与本单位密切相关的软件单位。 迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖，因此，很容易使得系统的功能模块功能独立，相互之间不存在（或很少有）依赖关系。 </p>
<p>迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系，也希望能通过它的友元类来转达。因此，应用迪米特法则有可能造成的一个后果就是：系统中存在大量的中介类，这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。 设计模式的门面模式（Facade）和中介模式（Mediator），都是应用的例子。 </p>
<h2 id="设计模式"><a href="#设计模式" class="headerlink" title="设计模式"></a>设计模式</h2><h3 id="创建型模式"><a href="#创建型模式" class="headerlink" title="创建型模式"></a>创建型模式</h3><p>创建型模式的共同作用：创建模式抽象了实例化的过程，它们帮助一个系统独立于如何创建、组合和表示它们的哪些对象，将关于系统使用哪些具体的类信息封装起来，允许使用者用结构、功能差别很大的“产品”对象来配置系统，其配置可以是静态，也可以是动态的。</p>
<h4 id="简单工厂模式"><a href="#简单工厂模式" class="headerlink" title="简单工厂模式"></a>简单工厂模式</h4><p><strong>在实现功能中，为了确保代码的低耦合性，根据单一职责原则，一个类只负责一个功能领域中的相应职责。</strong>因此，在选择实例化对象以实现功能时，需要进行情况的判断，这个判断处于的地方就是工厂类。 工厂类的作用是：根据不同的情况，实例化出不同类的对象，从而实现相应的功能，同时确保了代码的高内聚、低耦合。  </p>
<h4 id="工厂方法模式"><a href="#工厂方法模式" class="headerlink" title="工厂方法模式"></a>工厂方法模式</h4><p><strong>工厂方法模式：定义一个用于创建对象的接口，用子类决定实例化哪一个类。</strong>工厂方法使一个类的实例化延迟到了其子类。 工厂方法模式模板结构：  工厂方法模式是对简单工厂模式的推广，使用多态性，但缺点是每添加一个产品就需要增加一个产品工厂的类，开发量较大。可利用反射来解决分支问题。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.PNG" alt="工厂方法模式"></p>
<h4 id="抽象工厂模式"><a href="#抽象工厂模式" class="headerlink" title="抽象工厂模式"></a>抽象工厂模式</h4><p>工厂模式方法是定义一个用于创建对象的接口，让子类来决定应该实例化哪一个类，每一个类代表一个工厂。 <strong>抽象工厂模式：提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。</strong> </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.PNG" alt="抽象工厂模式"></p>
<p> AbstractProductA和AbstractProductB是两个抽象产品，它们都有两种不同实现。而AbstractFactory是一个抽象工厂接口，包含所有产品创建对象的抽象方法。 其实通俗地来讲就是在工厂的层面再往上抽象一层，越往上层抽象，则相对依赖地就更少，同样，对于下层的依赖，使用反射的方法来进行依赖注入。</p>
<p>依赖注入：利用反射+配置文件实现数据访问程序。反射是指：在运行状态中，对于任意一个类都可以反射来获取程序在运行时刻的内部结构（如：属性与方法）。使用反射API的时候就好像在看一个Java类在水中的倒影一样。知道了Java类的内部 结构之后，就可以与它进行交互，包括创建新的对象和调用对象中的方法等。这种交互方式与直接在源代码中使用的效果是相同的，但是又额外提供了运行时刻的灵活性，即可扩展性好。使用反射的一个最大的弊端是性能较差。 </p>
<h4 id="建造者模式"><a href="#建造者模式" class="headerlink" title="建造者模式"></a>建造者模式</h4><p><strong>建造者模式：将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。</strong>  上述的工厂模式是为了批量构建相似类型的对象，因此被称为工厂，而建造者模式是为了构建一个复杂对象的各个部件，保证对象的基本功能没有缺失，同时保证不同实例可实现不同特定功能。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F.PNG" alt="建造者模式"></p>
<p>Builder：是创建一个Product对象的各个部件指定的抽象接口，后续的建造类需实现该抽象类中定义的所有方法，这样保证了建造出产品的基本功能没有缺失。 ConcreteBuilder：具体建造者，实现Builder接口，构造、装配各个部件。 Director：指挥者，用来根据用户的需求来构建对象，即构建一个使用Builder接口的对象。 <strong>建造者模式使得建造代码与表示代码分离，由于建造者隐藏了该产品是如何组装的，所以如若需要改变一个产品的内部表示，只需要再定义一个具体建造者</strong>。 </p>
<h4 id="原型模式"><a href="#原型模式" class="headerlink" title="原型模式"></a>原型模式</h4><p><strong>原型模式：用原型实例制定创建对象的种类，并且通过拷贝这些原型创建新的对象。原型模式其实就是从一个对象再创建另外一个可定制的对象，且不需知道任何创建的细节。</strong></p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F.PNG" alt="原型模式"></p>
<p> 原型模式的结构图如上：抽象类的关键在于其Clone方法。  使用原型模式时，要注意下深拷贝与浅拷贝的问题。</p>
<h4 id="单例模式"><a href="#单例模式" class="headerlink" title="单例模式"></a>单例模式</h4><p><strong>单例模式：保证一个类仅有一个实例，并且提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问，但它不能防止你实例化多个对象。一个最好的办法就是，让类自身负责保存它的唯一实例。</strong>这个类可以保证没有其他实例可以被创建，并且还可以提供一个访问该实例的方法。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F.PNG" alt="单例模式"></p>
<h3 id="结构型模式"><a href="#结构型模式" class="headerlink" title="结构型模式"></a>结构型模式</h3><p>结构型模式往往是在系统构建好之后，如何去维护、处理其各个模块之间的依赖、耦合关系，如果以更加少耦合地情况给系统添加新的功能，同时确保各个模块之间的通信与数据处理。；</p>
<h4 id="适配器模式"><a href="#适配器模式" class="headerlink" title="适配器模式"></a>适配器模式</h4><p><strong>适配器模式：将一个类的接口转换成客户希望的另外一个接口，适配器模式使得原本由于接口不兼容而不能工作的类可以一起工作。</strong></p>
<p>应用环境：让接口不同的类通过适配后协同工作。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F.PNG" alt="适配器模式"></p>
<h4 id="桥接模式"><a href="#桥接模式" class="headerlink" title="桥接模式"></a>桥接模式</h4><p> <strong>桥接模式：将抽象部分与它的实现部分相分离，使他们都可以独立地变化。</strong>这里的分离并不是让抽象类与其派生类分离，实现指的是抽象类和它的派生类用来实现自己的对象。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F.PNG" alt="桥接模式"></p>
<p><strong>桥接模式的本质：实现系统可能有多角度分类，每一种分类都有可能变化，那么就把这种多角度分离出来让他们独立变化，减少之间的耦合。</strong>即把两个角色的继承关系改成组合关系，从而应对各自独立的变化。</p>
<h4 id="组合模式"><a href="#组合模式" class="headerlink" title="组合模式"></a>组合模式</h4><p><strong>组合模式：将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。</strong>  组合模式应用场景：需求中是体现部分与整体层次的结构时，以及你希望用户可以忽略组合对象与单个对象的不同，统一地使用组合结构中的所有对象时。 </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F.PNG" alt="组合模式"></p>
<h4 id="装饰模式"><a href="#装饰模式" class="headerlink" title="装饰模式"></a>装饰模式</h4><p><strong>装饰模式：动态地给一个对象添加一些额外的职责，就增加功能来说，装饰模式比生成子类更加灵活</strong>。 </p>
<p>装饰模式模板结构： (1)：Component类：定义一个对象接口，可以动态地添加职责，同时作为一个抽象接口，遵循依赖倒置原则。 (2)：ConcreteComponent类：继承与Component类，定义具体对象，可以给对象添加具体的职责； (3)：Decorator：装饰抽象类，继承了Component，且从外类来扩展Component类的功能；但对于Component来说，无需知道Decorator的存在。  </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F.PNG" alt="装饰器模式"></p>
<p>装饰模式利用SetComponent来对对象进行包装，这样每个装饰对象的实现就和如何使用这个对象分离开了，每个装饰对象只关心自己的功能，不关心如何被添加到对象链中。 </p>
<p>装饰模式解析： (1)：装饰模式是为已有功能动态地添加等多功能的一种方式，当系统需要新功能时，往旧的类中添加新代码往往会增加主类的复杂程度。 (2)：装饰模式将每个要装饰的功能放在单独的类中，并让该类包装其所要装饰的对象，因此当需要执行特殊行为时，客户端代码可在运行时，有选择地使用装饰功能包装对象。</p>
<h4 id="外观模式-门面模式"><a href="#外观模式-门面模式" class="headerlink" title="外观模式(门面模式)"></a>外观模式(门面模式)</h4><p><strong>外观模式：为子系统中的一组接口提供一个一致的界面，此模式定义了一个高层接口，该接口使得该子系统更加容易使用。</strong>同时引入一个外观对象，让其为子系统提供了一个单一而简单的屏障。</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F.PNG" alt="外观模式"></p>
<p>外观模式应用场景：1、在设计阶段，应当有意识地将不同的两个层分离，例如MVVM架构，为不同的子系统间提供简单的接口； 2、开发阶段：子系统因为不断的重构演化而变得越来越复杂时，增加外观模式提供简单的接口，减少不同模块间的依赖； 3、维护遗留的大型系统时，该系统已经难以维护与扩展，因此可以为新系统设计一个外观类，来提供针对老系统的简单化接口；再让新系统与这个外观类进行交互，减少对老系统的维护成本。</p>
<h4 id="享元模式"><a href="#享元模式" class="headerlink" title="享元模式"></a>享元模式</h4><p><strong>享元模式：运用共享技术有效地支持大量细粒度的对象。  享元模式可以避免大量非常相似类的开销</strong>；</p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F.PNG" alt="享元模式"></p>
<p>在程序设计中，有时需要生成大量细粒度的类实例来表示的护具，若该实例除了几个参数基本相同；如果能把这些参数移到类实例的外面，在方法调用时再将他们传递进来，就可通过共享大幅降低单个实例的数目。 享元模式应用：如果一个应用程序使用了大量的对象，且大量的对象造成了很大的存储开销时，则可以考虑使用；还有就是大量的对象状态可由外部状态来控制，这样可用较少的共享对象取代多组对象。</p>
<h4 id="代理模式"><a href="#代理模式" class="headerlink" title="代理模式"></a>代理模式</h4><p><strong>代理模式：为其他对象提供一种代理以控制对这个对象的访问。</strong> 代理模式模板结构： (1)：Subject类：定义了RealSubject和Proxy的共用接口，这样就在任何使用RealSubject的地方均使用Proxy。 (2)：RealSubject类：定义Proxy所代表的真实实体。 (3)：Proxy类：保存一个引用使得代理可以访问实体，并提供一个与Subject的接口相同的接口，这样代理可以用来替代实体。  </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F.PNG" alt="代理模式"></p>
<p>代理模式应用： (1)：远程代理：为一个对象在不同的地址空间提供局部代表，例如：在应用程序的项目中加入一个Web引用； (2)：虚拟代理：根据需要创建开销大的对象，用于存放实例化需要很久的对象；例如：HTML网页加载图片的过程，通过虚拟代理替代真实图片； (3)：安全代理：用来控制真实对象访问时的权限 (4)：智能指引：当调用真实对象时，代理处理另外一些事。    </p>
<h3 id="行为型模式"><a href="#行为型模式" class="headerlink" title="行为型模式"></a>行为型模式</h3><h4 id="观察者模式"><a href="#观察者模式" class="headerlink" title="观察者模式"></a>观察者模式</h4><p><strong>观察者模式：又称为发布-订阅模式，定义了一对多的依赖关系，让多个观察者对象同时监听某一个主题对象。该主题对象在状态发生变化时，会通知所有观察者对象，使他们能够更新自己。</strong>  其实本质就是一个抽象观察者类、一个抽象通知者类，之后的具体实现都是对该类的继承实现。常用于一个对象改变需要同时改变其他对象的时候。 </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F.PNG" alt="观察者模式"></p>
<p>Subject类：抽象通知者；1、抽象主题应该提供接口，删除或增加观察者对象；2、提供Notify方法通知观察者对象； Observer类：抽象观察者；1、更新接口，在收到Notify通知时，更新个人状态； ConcreteSubject：具体通知者，存入通知的具体状态； ConcretrObserver：具体观察者，实现要求的更新接口，同时保存一个指向具体通知者的引用，可修改具体通知者的通知状态。 </p>
<p>观察者模式解析：系统分割为相互协作类时，需要维护相关对象间的一致性，但我们不希望为了维持一致性而使各类紧密耦合，这样维护、扩展、重用都会有问题。而观察者模式的关键在于Subject，一旦Subject状态怪变，所有Observer得到通知，而观察者间并无联系。关键在于解除耦合：让耦合的双方都依赖于抽象，而不是依赖于聚义，从而使各自变化不会影响另一边变化。 </p>
<p>事件委托实现：委托就是一种引用方法的类型。一旦为委托分配了方法，委托将与该方法具有完全相同的行为，委托方法的使用可以像其他任何方法一样，具有参数和返回值，可以看做是对函数的抽象。 一个委托可以搭载多个方法，所有方法被依次唤起，且其可以使得委托对象所搭载的方法并不需要属于同一个类。 </p>
<h4 id="模板方法模式"><a href="#模板方法模式" class="headerlink" title="模板方法模式"></a>模板方法模式</h4><p><strong>模板方法模式：定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。</strong></p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.PNG" alt="模板方法模式"></p>
<p>模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。  模板方法模式的本质：1、当不变的和可变的行为在方法的子类实现中混合在一起的时候，不变的行为就会在子类中重复出现。2、我们通过模板方法模式把这些行为搬移到单一的地方，这样就能够帮助子类拜托重复的不变行为的纠缠。 </p>
<h4 id="命令模式"><a href="#命令模式" class="headerlink" title="命令模式"></a>命令模式</h4><p><strong>命令模式：将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化；对请求排队或记录请求日志，以及支持可撤销的操作。</strong>  命令模式的应用：1、较容易设计命令队列；2、容易将命令计入日志；3、允许接受请求的一方决定是否要否决请求；4、容易实现请求撤销；5、容易新加命令类。 </p>
<p><img src="/../../image/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F.PNG" alt="命令模式"></p>
<h4 id="策略模式"><a href="#策略模式" class="headerlink" title="策略模式"></a>策略模式</h4><p>面对对象的编程模式，并不是类越多越好，类的划分是为了封装，但分类的基础是抽象，具有相同属性和功能的对象的抽象集合才是类，我们需要先通过抽象分析找出集合，并将每个集合定义为类。每次需要扩展功能时，则添加新的抽象类，并利用简单工厂模式来判断使用哪个抽象类。 </p>
<p>但利用简单工厂模式来管理时，面对算法的时常变动，每次维护、扩展都需要重新修改、编译该工厂函数，这个时候就可以使用策略模式。 策略模式：定义了算法家族，并将其分别封装起来，让它们之间可以互相替换，此模式让算法的变化，不会影响到使用算法文档客户。 </p>
<p>策略模式模板结构： (1)：Strategy类：定义所有支持的算法的公共接口； (2)：ConcreteStrategy类：封装了具体的算法、行为，继承于Strategy； (3)：Context类：用一个ConcreteStrategy来配置，维护对一个Strategy对象的引用。在初始化时，传入具体的策略对象，从而根据具体的策略对象来调用具体的算法方法。  </p>
<p>策略模式解析： (1)：本质是一种定义一系列算法的方法，这些算法完成相同的工作，只是实现不同，其以相同方式调用所有算法，减少了使用者与算法的耦合； (2)：其Strategy类为Context定义了一系列的可供重用的算法或行为，通过这种继承方式，有助于析取算法的公共功能； (3)：策略模式简化了单元测试是，每个算法有其单独类，从而可通过接口单独测试。 (4)：本质上，策略模式其实是用于封装各种不同的规则，使其成为一个个独立的类，最终减少switch语句的应用。一般只要在分析过程中需要在不同的时间应用不同的业务规则，就可以考虑使用策略模式来处理变化。 </p>
<h4 id="状态模式"><a href="#状态模式" class="headerlink" title="状态模式"></a>状态模式</h4><p>状态模式：当一个对象的内在状态改变时，允许改变其行为，这个对象看起来像是改变了其类。 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时，把状态的判断逻辑转移到表示不同状态的一系列类中，可以将复杂的判断逻辑简化。  状态模式应用：当一个对象的行为取决于它的状态时，并且它必须在运行时刻根据状态改变它的行为时，就可以考虑状态模式了。由于与状态相关的代码都存在于某个ConcreteState中，所以定义新的子类可以容易地增加新的状态和转换。  </p>
<h4 id="备忘录模式"><a href="#备忘录模式" class="headerlink" title="备忘录模式"></a>备忘录模式</h4><p>备忘录模式：在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态，这样就可以在之后将该对象恢复到原先保存的状态。   </p>
<h4 id="组合模式-1"><a href="#组合模式-1" class="headerlink" title="组合模式"></a>组合模式</h4><p>组合模式：将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。  组合模式应用场景：需求中是体现部分与整体层次的结构时，以及你希望用户可以忽略组合对象与单个对象的不同，统一地使用组合结构中的所有对象时。 </p>
<h4 id="迭代器模式"><a href="#迭代器模式" class="headerlink" title="迭代器模式"></a>迭代器模式</h4><p>迭代器模式：提供一种方法顺序访问一个聚合对象中各个元素，且不暴露该对象的内部表示。   </p>
<h4 id="职责链模式"><a href="#职责链模式" class="headerlink" title="职责链模式"></a>职责链模式</h4><p>职责链模式：使得多个对象都有机会处理请求，从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链，并沿着该链传递请求，直到有一个对象处理它为止。  职责链的应用：使接受者与发送者都没有对方的明确信息，且链中的对象自己也并不知道链的结构，结果是职责链可简化对象的相互谅解，仅需要保持一个指向后继者的引用，而不需要保持所有的候选者引用。 </p>
<h4 id="中介者模式"><a href="#中介者模式" class="headerlink" title="中介者模式"></a>中介者模式</h4><p>中介者模式：用一个中介对象来封装一系列对象的交互。中介者使各对象不需要显式地相互引用，从而使其耦合松散，而且可以独立地改变他们之间的交互。  中介者模式很容易在系统中运用，同样也很容易在系统中误用，当系统中出现了“多对多”交互复杂的对象群时，不要急于使用中介者，而是先反思系统设计是否合理。中介者的出现减少了各个部分的耦合，但同样将交互复杂性变为了中介者的复杂性，这使得中介者会变得比任一个模块更复杂。 </p>
<h4 id="解释器模式"><a href="#解释器模式" class="headerlink" title="解释器模式"></a>解释器模式</h4><p>解释器模式：给定一个语言，定义它的文法的一种表示，并定义一个解释器，用于解释语言中的句子。  例如：JSX解析器babel；vue的模板语法解释器template。</p>
<h4 id="访问者模式"><a href="#访问者模式" class="headerlink" title="访问者模式"></a>访问者模式</h4><p>访问者模式：表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。  访问者模式适用于数据结构相对稳定的系统，其目的是将处理从数据结构中分离出来，将其余作用于结构上的操作解耦。访问者模式的优点是：新增操作很容易，新增一个访问者即可，但缺点是新增新的数据结构就比较困难。例如：redux、vuex，这些组件状态管理工具。 */</p>

    </div>
    
    
    
    
    <div>
      
        <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div>
    
</div>

      
    </div>
        <div class="reward-container">
  <div>坚持原创技术分享，您的支持将鼓励我继续创作！</div>
  <button onclick="var qr = document.getElementById('qr'); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/images/alipay.png" alt="Li Yudong 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>

        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>Li Yudong
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="http://example.com/2021/07/22/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%88%9D%E8%AF%86%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" title="初识设计模式">http://example.com/2021/07/22/设计模式/初识设计模式/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

    
      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="tag"># 设计模式</a>
          </div>
    
        

    
        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2021/07/17/vue%E6%BA%90%E7%A0%81/vue%E7%BB%84%E4%BB%B6%E5%8C%96/" rel="prev" title="vue组件化">
      <i class="fa fa-chevron-left"></i> vue组件化
    </a></div>
      <div class="post-nav-item">
    <a href="/2021/07/25/vue%E6%BA%90%E7%A0%81/vue%E5%AE%98%E7%BD%91/" rel="next" title="vue官方文档">
      vue官方文档 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#初识设计模式"><span class="nav-number">1.</span> <span class="nav-text">初识设计模式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#设计模式原则"><span class="nav-number">1.1.</span> <span class="nav-text">设计模式原则</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#单一职责原则"><span class="nav-number">1.1.1.</span> <span class="nav-text">单一职责原则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#开放封闭原则"><span class="nav-number">1.1.2.</span> <span class="nav-text">开放封闭原则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#里氏代换原则"><span class="nav-number">1.1.3.</span> <span class="nav-text">里氏代换原则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#依赖倒转原则"><span class="nav-number">1.1.4.</span> <span class="nav-text">依赖倒转原则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#接口隔离原则"><span class="nav-number">1.1.5.</span> <span class="nav-text">接口隔离原则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#迪米特法则"><span class="nav-number">1.1.6.</span> <span class="nav-text">迪米特法则</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#设计模式"><span class="nav-number">1.2.</span> <span class="nav-text">设计模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#创建型模式"><span class="nav-number">1.2.1.</span> <span class="nav-text">创建型模式</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#简单工厂模式"><span class="nav-number">1.2.1.1.</span> <span class="nav-text">简单工厂模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#工厂方法模式"><span class="nav-number">1.2.1.2.</span> <span class="nav-text">工厂方法模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#抽象工厂模式"><span class="nav-number">1.2.1.3.</span> <span class="nav-text">抽象工厂模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#建造者模式"><span class="nav-number">1.2.1.4.</span> <span class="nav-text">建造者模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#原型模式"><span class="nav-number">1.2.1.5.</span> <span class="nav-text">原型模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#单例模式"><span class="nav-number">1.2.1.6.</span> <span class="nav-text">单例模式</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#结构型模式"><span class="nav-number">1.2.2.</span> <span class="nav-text">结构型模式</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#适配器模式"><span class="nav-number">1.2.2.1.</span> <span class="nav-text">适配器模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#桥接模式"><span class="nav-number">1.2.2.2.</span> <span class="nav-text">桥接模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#组合模式"><span class="nav-number">1.2.2.3.</span> <span class="nav-text">组合模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#装饰模式"><span class="nav-number">1.2.2.4.</span> <span class="nav-text">装饰模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#外观模式-门面模式"><span class="nav-number">1.2.2.5.</span> <span class="nav-text">外观模式(门面模式)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#享元模式"><span class="nav-number">1.2.2.6.</span> <span class="nav-text">享元模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#代理模式"><span class="nav-number">1.2.2.7.</span> <span class="nav-text">代理模式</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#行为型模式"><span class="nav-number">1.2.3.</span> <span class="nav-text">行为型模式</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#观察者模式"><span class="nav-number">1.2.3.1.</span> <span class="nav-text">观察者模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#模板方法模式"><span class="nav-number">1.2.3.2.</span> <span class="nav-text">模板方法模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令模式"><span class="nav-number">1.2.3.3.</span> <span class="nav-text">命令模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#策略模式"><span class="nav-number">1.2.3.4.</span> <span class="nav-text">策略模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#状态模式"><span class="nav-number">1.2.3.5.</span> <span class="nav-text">状态模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#备忘录模式"><span class="nav-number">1.2.3.6.</span> <span class="nav-text">备忘录模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#组合模式-1"><span class="nav-number">1.2.3.7.</span> <span class="nav-text">组合模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#迭代器模式"><span class="nav-number">1.2.3.8.</span> <span class="nav-text">迭代器模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#职责链模式"><span class="nav-number">1.2.3.9.</span> <span class="nav-text">职责链模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#中介者模式"><span class="nav-number">1.2.3.10.</span> <span class="nav-text">中介者模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#解释器模式"><span class="nav-number">1.2.3.11.</span> <span class="nav-text">解释器模式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#访问者模式"><span class="nav-number">1.2.3.12.</span> <span class="nav-text">访问者模式</span></a></li></ol></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Li Yudong"
      src="/images/author.jpg">
  <p class="site-author-name" itemprop="name">Li Yudong</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">95</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">14</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">18</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/tiarmor1" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;tiarmor1" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:1157019137@qq.com" title="E-Mail → mailto:1157019137@qq.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
  </div>
  <div class="cc-license motion-element" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" rel="noopener" target="_blank"><img src="/images/cc-by-nc-sa.svg" alt="Creative Commons"></a>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 2020 – 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Li Yudong</span>
</div>

        








      </div>
    </footer>
  </div>

  
  
  <script color='0,0,0' opacity='0.5' zIndex='-1' count='150' src="/lib1/canvas-nest/canvas-nest.min.js"></script>
  <script src="/lib1/anime.min.js"></script>
  <script src="/lib1/velocity/velocity.min.js"></script>
  <script src="/lib1/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  




  
<script src="/js/local-search.js"></script>













  

  

  
   <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas> 
   <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> 
   <script type="text/javascript" src="/js/fireworks.js"></script>
  
</body>
</html>

